home *** CD-ROM | disk | FTP | other *** search
-
-
- #import "UPath.h"
- #import "PSWUPath.h"
-
- @interface UPath(PrivateMethods)
-
- - growParams;
- - growOps;
-
- @end
-
- @implementation UPath
-
- //************************************************************************
- // creating and destroying
-
- - initCountParams:(int)numParams countOps:(int)numOps
- {
- [super init];
- maxParams = numParams;
- maxOps = numOps;
- bboxParams = (float *)NXZoneMalloc([self zone],sizeof(float) * (maxParams + 4));
- bbox = bboxParams;
- params = &bboxParams[4];
- bboxOps = (char *)NXZoneMalloc([self zone],maxOps + 2);
- ops = &bboxOps[2];
- ping = NO;
- [self resetFill];
- return self;
- }
-
- - init
- {
- [self initCountParams:32 countOps:16];
- return self;
- }
-
- - free
- {
- NX_FREE(bboxParams);
- NX_FREE(bboxOps);
- return [super free];
- }
-
- - copyFromZone:(NXZone *)zone
- {
- UPath *theCopy;
-
- theCopy = [super copyFromZone:zone];
- theCopy->bboxParams = NXZoneMalloc(zone,sizeof(float) * (maxParams + 4));
- theCopy->bboxOps = NXZoneMalloc(zone,maxOps + 2);
- bcopy(bboxParams,theCopy->bboxParams,(sizeParams + 4) * (sizeof(float)/sizeof(char)));
- bcopy(bboxOps,theCopy->bboxOps,sizeOps + 2);
- theCopy->bbox = theCopy->bboxParams;
- theCopy->params = theCopy->bboxParams + 4 * sizeof(float);
- theCopy->ops = theCopy->bboxOps + 2;
- return theCopy;
- }
-
- //************************************************************************
- // accessing
-
- - getBounds:(NXRect *)aRect
- {
- NXSetRect(aRect,bbox[0],bbox[1],bbox[2] - bbox[0],bbox[3] - bbox[1]);
- return self;
- }
-
- //************************************************************************
- // defining user path
-
- - resetFill
- {
- sizeParams = sizeOps = 0;
- cp.x = cp.y = 0.0;
- bbox[0] = bbox[1] = 1.0e6;
- bbox[2] = bbox[3] = -1.0e6;
- bboxOps[0] = dps_ucache;
- bboxOps[1] = dps_setbbox;
- return self;
- }
-
- - updateBBoxOnX:(float)x andY:(float)y
- {
- if(x < bbox[0])
- bbox[0] = x;
- if(y < bbox[1])
- bbox[1] = y;
- if(x > bbox[2])
- bbox[2] = x;
- if(y > bbox[3])
- bbox[3] = y;
- return self;
- }
-
- - moveto:(float)x :(float)y
- {
- if(sizeParams + 2 > maxParams)
- if(![self growParams])
- return nil;
- if(sizeOps + 1 > maxOps)
- if(![self growOps])
- return nil;
- params[sizeParams++] = x;
- params[sizeParams++] = y;
- ops[sizeOps++] = dps_moveto;
- [self updateBBoxOnX:x andY:y];
- cp.x = x;
- cp.y = y;
- return self;
- }
-
- - rmoveto:(float)x :(float)y
- {
- if(sizeParams + 2 > maxParams)
- if(![self growParams])
- return nil;
- if(sizeOps + 1 > maxOps)
- if(![self growOps])
- return nil;
- ops[sizeOps++] = dps_rmoveto;
- params[sizeParams++] = x;
- params[sizeParams++] = y;
- cp.x += x;
- cp.y += y;
- [self updateBBoxOnX:cp.x andY:cp.y];
- return self;
- }
-
- - lineto:(float)x :(float)y
- {
- if(sizeParams + 2 > maxParams)
- if(![self growParams])
- return nil;
- if(sizeOps + 1 > maxOps)
- if(![self growOps])
- return nil;
- ops[sizeOps++] = dps_lineto;
- params[sizeParams++] = x;
- params[sizeParams++] = y;
- [self updateBBoxOnX:x andY:y];
- cp.x = x;
- cp.y = y;
- return self;
- }
-
- - rlineto:(float)x :(float)y
- {
- if(sizeParams + 2 > maxParams)
- if(![self growParams])
- return nil;
- if(sizeOps + 1 > maxOps)
- if(![self growOps])
- return nil;
- ops[sizeOps++] = dps_rlineto;
- params[sizeParams++] = x;
- params[sizeParams++] = y;
- cp.x += x;
- cp.y += y;
- [self updateBBoxOnX:cp.x andY:cp.y];
- return self;
- }
-
- - curveto:(float)x1 :(float)y1 :(float)x2 :(float)y2 :(float)x3 :(float)y3
- {
- if(sizeParams + 6 > maxParams)
- if(![self growParams])
- return nil;
- if(sizeOps + 1 > maxOps)
- if(![self growOps])
- return nil;
- ops[sizeOps++] = dps_curveto;
- params[sizeParams++] = x1;
- params[sizeParams++] = y1;
- [self updateBBoxOnX:x1 andY:y1];
- params[sizeParams++] = x2;
- params[sizeParams++] = y2;
- [self updateBBoxOnX:x2 andY:y2];
- params[sizeParams++] = x3;
- params[sizeParams++] = y3;
- [self updateBBoxOnX:x3 andY:y3];
- cp.x = x3;
- cp.y = y3;
- return self;
- }
-
- - rcurveto:(float)dx1 :(float)dy1 :(float)dx2 :(float)dy2 :(float)dx3 :(float)dy3
- {
- if(sizeParams + 6 > maxParams)
- if(![self growParams])
- return nil;
- if(sizeOps + 1 > maxOps)
- if(![self growOps])
- return nil;
- ops[sizeOps++] = dps_rcurveto;
- params[sizeParams++] = dx1;
- params[sizeParams++] = dy1;
- params[sizeParams++] = dx2;
- params[sizeParams++] = dy2;
- params[sizeParams++] = dx3;
- params[sizeParams++] = dy3;
- [self updateBBoxOnX:cp.x + dx1 andY:cp.y + dx1];
- [self updateBBoxOnX:cp.x + dx2 andY:cp.y + dx2];
- [self updateBBoxOnX:cp.x + dx3 andY:cp.y + dx3];
- cp.x += dx3;
- cp.y += dy3;
- return self;
- }
-
- - arc:(float)x :(float)y :(float)r :(float)ang1 :(float)ang2
- {
- if(sizeParams + 5 > maxParams)
- if(![self growParams])
- return nil;
- if(sizeOps + 1 > maxOps)
- if(![self growOps])
- return nil;
- ops[sizeOps] = dps_arc;
- sizeOps = sizeOps + 1;
- params[sizeParams++] = x;
- params[sizeParams++] = y;
- params[sizeParams++] = r;
- params[sizeParams++] = ang1;
- params[sizeParams++] = ang2;
- [self updateBBoxOnX:x + r andY:y + r];
- [self updateBBoxOnX:x - r andY:y - r];
- cp.x = x + cos(ang2 / 57.3) * r;
- cp.y = y + sin(ang2 / 57.3) * r;
- return self;
- }
-
- - arcn:(float)x :(float)y :(float)r :(float)ang1 :(float)ang2
- {
- if(sizeParams + 5 > maxParams)
- if(![self growParams])
- return nil;
- if(sizeOps + 1 > maxOps)
- if(![self growOps])
- return nil;
- ops[sizeOps++] = dps_arcn;
- params[sizeParams++] = x;
- params[sizeParams++] = y;
- params[sizeParams++] = r;
- params[sizeParams++] = ang1;
- params[sizeParams++] = ang2;
- [self updateBBoxOnX:x + r andY:y + r];
- [self updateBBoxOnX:x - r andY:y - r];
- cp.x = x + cos(ang2 / 57.3) * r;
- cp.y = y + sin(ang2 / 57.3) * r;
- return self;
- }
-
- - arct:(float)x1 :(float)y1 :(float)x2 :(float)y2 :(float)r
- {
- if(sizeParams + 5 > maxParams)
- if(![self growParams])
- return nil;
- if(sizeOps + 1 > maxOps)
- if(![self growOps])
- return nil;
- ops[sizeOps++] = dps_arct;
- params[sizeParams++] = x1;
- params[sizeParams++] = y1;
- params[sizeParams++] = x2;
- params[sizeParams++] = y2;
- params[sizeParams++] = r;
- [self updateBBoxOnX:x1 andY:y1];
- [self updateBBoxOnX:x2 andY:y2];
- cp.x = x2;
- cp.y = y2;
- return self;
- }
-
- - closepath
- {
- ops[sizeOps++] = dps_closepath;
- return self;
- }
-
-
- //************************************************************************
- // sending
-
- - debugSend:(int)op cached:(BOOL)cache
- {
- ping = YES;
- return [self send:op cached:cache];
- }
-
- - send:(int)op cached:(BOOL)cache
- {
- NXHandler exception;
-
- exception.code = 0;
- NX_DURING
- if(cache)
- DPSDoUserPath(params, sizeParams, dps_float, bboxOps,
- sizeOps + 2, bbox, op);
- else
- DPSDoUserPath(params, sizeParams, dps_float, bboxOps + 1,
- sizeOps + 1, bbox, op);
- if(ping)
- NXPing();
- NX_HANDLER
- exception = NXLocalHandler;
- NX_ENDHANDLER
- if(exception.code){
- NXReportError(&exception);
- return nil;
- } else
- return self;
- }
-
- //************************************************************************
- // archiving
-
- - write:(NXTypedStream *)stream
- {
- [super write:stream];
- NXWriteTypes(stream,"iiii",&sizeParams,&sizeOps,&maxParams,&maxOps);
- NXWritePoint(stream,&cp);
- NXWriteArray(stream,"f",sizeParams + 4,bboxParams);
- NXWriteArray(stream,"c",sizeOps + 2,bboxOps);
- return self;
- }
-
- - read:(NXTypedStream *)stream
- {
- [super read:stream];
- NXReadTypes(stream,"iiii",&sizeParams,&sizeOps,&maxParams,&maxOps);
- NXReadPoint(stream,&cp);
- bboxParams = NXZoneMalloc([self zone],sizeof(float) * (maxParams + 4));
- bboxOps = NXZoneMalloc([self zone],maxOps + 2);
- NXReadArray(stream,"f",sizeParams + 4,bboxParams);
- NXReadArray(stream,"c",sizeOps + 2,bboxOps);
- return self;
- }
-
- - awake
- {
- [super awake];
- ping = NO;
- bbox = bboxParams;
- params = &bboxParams[4];
- ops = &bboxOps[2];
- return self;
- }
-
- @end
-
- @implementation UPath(PrivateMethods)
-
- - growParams
- {
- maxParams *= 2;
- bbox = bboxParams = (float *)NXZoneRealloc([self zone], bboxParams,sizeof(float) * (maxParams + 4));
- params = &bboxParams[4];
- return self;
- }
-
- - growOps
- {
- maxOps *= 2;
- bboxOps = (char *)NXZoneRealloc([self zone], bboxOps,maxOps + 2);
- ops = &bboxOps[2];
- return self;
- }
-
- @end
-